home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 10868 / 10868.xpi / modules / engines / passwords.js < prev    next >
Text File  |  2010-02-11  |  9KB  |  283 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is Bookmarks Sync.
  15.  *
  16.  * The Initial Developer of the Original Code is Mozilla.
  17.  * Portions created by the Initial Developer are Copyright (C) 2008
  18.  * the Initial Developer. All Rights Reserved.
  19.  *
  20.  * Contributor(s):
  21.  *  Justin Dolske <dolske@mozilla.com>
  22.  *  Anant Narayanan <anant@kix.in>
  23.  *
  24.  * Alternatively, the contents of this file may be used under the terms of
  25.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  26.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  27.  * in which case the provisions of the GPL or the LGPL are applicable instead
  28.  * of those above. If you wish to allow use of your version of this file only
  29.  * under the terms of either the GPL or the LGPL, and not to allow others to
  30.  * use your version of this file under the terms of the MPL, indicate your
  31.  * decision by deleting the provisions above and replace them with the notice
  32.  * and other provisions required by the GPL or the LGPL. If you do not delete
  33.  * the provisions above, a recipient may use your version of this file under
  34.  * the terms of any one of the MPL, the GPL or the LGPL.
  35.  *
  36.  * ***** END LICENSE BLOCK ***** */
  37.  
  38. const EXPORTED_SYMBOLS = ['PasswordEngine'];
  39.  
  40. const Cu = Components.utils;
  41. const Cc = Components.classes;
  42. const Ci = Components.interfaces;
  43.  
  44. Cu.import("resource://weave/constants.js");
  45. Cu.import("resource://weave/util.js");
  46. Cu.import("resource://weave/engines.js");
  47. Cu.import("resource://weave/stores.js");
  48. Cu.import("resource://weave/trackers.js");
  49. Cu.import("resource://weave/base_records/collection.js");
  50. Cu.import("resource://weave/ext/Observers.js");
  51. Cu.import("resource://weave/type_records/passwords.js");
  52.  
  53. function PasswordEngine() {
  54.   this._init();
  55. }
  56. PasswordEngine.prototype = {
  57.   __proto__: SyncEngine.prototype,
  58.   name: "passwords",
  59.   _displayName: "Passwords",
  60.   description: "Forget all your passwords, Weave will remember them for you",
  61.   logName: "Passwords",
  62.   _storeObj: PasswordStore,
  63.   _trackerObj: PasswordTracker,
  64.   _recordObj: LoginRec,
  65.  
  66.   _syncFinish: function _syncFinish() {
  67.     SyncEngine.prototype._syncFinish.call(this);
  68.  
  69.     // Delete the weave credentials from the server once
  70.     if (!Svc.Prefs.get("deletePwd", false)) {
  71.       try {
  72.         let ids = Svc.Login.findLogins({}, PWDMGR_HOST, "", "").map(function(info)
  73.           info.QueryInterface(Components.interfaces.nsILoginMetaInfo).guid);
  74.         let coll = new Collection(this.engineURL);
  75.         coll.ids = ids;
  76.         let ret = coll.delete();
  77.         this._log.debug("Delete result: " + ret);
  78.  
  79.         Svc.Prefs.set("deletePwd", true);
  80.       }
  81.       catch(ex) {
  82.         this._log.debug("Password deletes failed: " + Utils.exceptionStr(ex));
  83.       }
  84.     }
  85.   },
  86.  
  87.   _findDupe: function _findDupe(item) {
  88.     let login = this._store._nsLoginInfoFromRecord(item);
  89.     let logins = Svc.Login.findLogins({}, login.hostname, login.formSubmitURL,
  90.       login.httpRealm);
  91.  
  92.     // Look for existing logins that match the hostname but ignore the password
  93.     for each (let local in logins)
  94.       if (login.matches(local, true) && local instanceof Ci.nsILoginMetaInfo)
  95.         return local.guid;
  96.   }
  97. };
  98.  
  99. function PasswordStore() {
  100.   this._init();
  101. }
  102. PasswordStore.prototype = {
  103.   __proto__: Store.prototype,
  104.   name: "passwords",
  105.   _logName: "PasswordStore",
  106.  
  107.   _nsLoginInfo: null,
  108.   _init: function PasswordStore_init() {
  109.     Store.prototype._init.call(this);
  110.     this._nsLoginInfo = new Components.Constructor(
  111.       "@mozilla.org/login-manager/loginInfo;1",
  112.       Ci.nsILoginInfo,
  113.       "init"
  114.     );
  115.   },
  116.  
  117.   _nsLoginInfoFromRecord: function PasswordStore__nsLoginInfoRec(record) {
  118.     let info = new this._nsLoginInfo(record.hostname,
  119.                                      record.formSubmitURL,
  120.                                      record.httpRealm,
  121.                                      record.username,
  122.                                      record.password,
  123.                                      record.usernameField,
  124.                                      record.passwordField);
  125.     info.QueryInterface(Ci.nsILoginMetaInfo);
  126.     info.guid = record.id;
  127.     return info;
  128.   },
  129.  
  130.   _getLoginFromGUID: function PasswordStore__getLoginFromGUID(id) {
  131.     let prop = Cc["@mozilla.org/hash-property-bag;1"].
  132.       createInstance(Ci.nsIWritablePropertyBag2);
  133.     prop.setPropertyAsAUTF8String("guid", id);
  134.  
  135.     let logins = Svc.Login.searchLogins({}, prop);
  136.     if (logins.length > 0) {
  137.       this._log.trace(logins.length + " items matching " + id + " found.");
  138.       return logins[0];
  139.     } else {
  140.       this._log.trace("No items matching " + id + " found. Ignoring");
  141.     }
  142.     return false;
  143.   },
  144.  
  145.   getAllIDs: function PasswordStore__getAllIDs() {
  146.     let items = {};
  147.     let logins = Svc.Login.getAllLogins({});
  148.  
  149.     for (let i = 0; i < logins.length; i++) {
  150.       // Skip over Weave password/passphrase entries
  151.       let metaInfo = logins[i].QueryInterface(Ci.nsILoginMetaInfo);
  152.       if (metaInfo.hostname == PWDMGR_HOST)
  153.         continue;
  154.  
  155.       items[metaInfo.guid] = metaInfo;
  156.     }
  157.  
  158.     return items;
  159.   },
  160.  
  161.   changeItemID: function PasswordStore__changeItemID(oldID, newID) {
  162.     this._log.trace("Changing item ID: " + oldID + " to " + newID);
  163.  
  164.     let oldLogin = this._getLoginFromGUID(oldID);
  165.     if (!oldLogin) {
  166.       this._log.trace("Can't change item ID: item doesn't exist");
  167.       return;
  168.     }
  169.     if (this._getLoginFromGUID(newID)) {
  170.       this._log.trace("Can't change item ID: new ID already in use");
  171.       return;
  172.     }
  173.  
  174.     let prop = Cc["@mozilla.org/hash-property-bag;1"].
  175.       createInstance(Ci.nsIWritablePropertyBag2);
  176.     prop.setPropertyAsAUTF8String("guid", newID);
  177.  
  178.     Svc.Login.modifyLogin(oldLogin, prop);
  179.   },
  180.  
  181.   itemExists: function PasswordStore__itemExists(id) {
  182.     if (this._getLoginFromGUID(id))
  183.       return true;
  184.     return false;
  185.   },
  186.  
  187.   createRecord: function PasswordStore__createRecord(guid, cryptoMetaURL) {
  188.     let record = new LoginRec();
  189.     let login = this._getLoginFromGUID(guid);
  190.  
  191.     record.id = guid;
  192.     if (login) {
  193.       record.encryption = cryptoMetaURL;
  194.       record.hostname = login.hostname;
  195.       record.formSubmitURL = login.formSubmitURL;
  196.       record.httpRealm = login.httpRealm;
  197.       record.username = login.username;
  198.       record.password = login.password;
  199.       record.usernameField = login.usernameField;
  200.       record.passwordField = login.passwordField;
  201.     }
  202.     else
  203.       record.deleted = true;
  204.     return record;
  205.   },
  206.  
  207.   create: function PasswordStore__create(record) {
  208.     this._log.debug("Adding login for " + record.hostname);
  209.     Svc.Login.addLogin(this._nsLoginInfoFromRecord(record));
  210.   },
  211.  
  212.   remove: function PasswordStore__remove(record) {
  213.     this._log.trace("Removing login " + record.id);
  214.  
  215.     let loginItem = this._getLoginFromGUID(record.id);
  216.     if (!loginItem) {
  217.       this._log.trace("Asked to remove record that doesn't exist, ignoring");
  218.       return;
  219.     }
  220.  
  221.     Svc.Login.removeLogin(loginItem);
  222.   },
  223.  
  224.   update: function PasswordStore__update(record) {
  225.     let loginItem = this._getLoginFromGUID(record.id);
  226.     if (!loginItem) {
  227.       this._log.debug("Skipping update for unknown item: " + record.hostname);
  228.       return;
  229.     }
  230.  
  231.     this._log.debug("Updating " + record.hostname);
  232.     let newinfo = this._nsLoginInfoFromRecord(record);
  233.     Svc.Login.modifyLogin(loginItem, newinfo);
  234.   },
  235.  
  236.   wipe: function PasswordStore_wipe() {
  237.     Svc.Login.removeAllLogins();
  238.   }
  239. };
  240.  
  241. function PasswordTracker() {
  242.   this._init();
  243. }
  244. PasswordTracker.prototype = {
  245.   __proto__: Tracker.prototype,
  246.   _logName: "PasswordTracker",
  247.   name: "passwords",
  248.   file: "password",
  249.  
  250.   _init: function PasswordTracker_init() {
  251.     Tracker.prototype._init.call(this);
  252.     Observers.add("passwordmgr-storage-changed", this);
  253.   },
  254.  
  255.   /* A single add, remove or change is 15 points, all items removed is 50 */
  256.   observe: function PasswordTracker_observe(aSubject, aTopic, aData) {
  257.     if (this.ignoreAll)
  258.       return;
  259.  
  260.     switch (aData) {
  261.     case 'modifyLogin':
  262.       aSubject = aSubject.QueryInterface(Ci.nsIArray).
  263.         queryElementAt(1, Ci.nsILoginMetaInfo);
  264.     case 'addLogin':
  265.     case 'removeLogin':
  266.       // Skip over Weave password/passphrase changes
  267.       aSubject.QueryInterface(Ci.nsILoginMetaInfo).
  268.         QueryInterface(Ci.nsILoginInfo);
  269.       if (aSubject.hostname == PWDMGR_HOST)
  270.         break;
  271.  
  272.       this.score += 15;
  273.       this._log.trace(aData + ": " + aSubject.guid);
  274.       this.addChangedID(aSubject.guid);
  275.       break;
  276.     case 'removeAllLogins':
  277.       this._log.trace(aData);
  278.       this.score += 500;
  279.       break;
  280.     }
  281.   }
  282. };
  283.